package main

import "fmt"

func main() {
	// 使用 make() 函数动态的构造切片：make( []Type, size, cap )
	// 其中 Type 是指切片的元素类型，
	// size 指的是为这个类型分配多少个元素，
	// cap 为预分配的元素数量，这个值设定后不影响 size，只是能提前分配空间，降低多次分配空间造成的性能问题。
	slice := make([]int, 5, 10)
	fmt.Println("len:", len(slice)) // 5
	fmt.Println("cap:", cap(slice)) // 10

	//  append() 函数为切片动态添加元素时，如果空间不足以容纳足够多的元素，切片就会进行“扩容”，此时新切片的长度会发生改变
	slice = append(slice, 1, 2, 3)
	slice = append(slice, []int{1, 2, 3}...) // 切片追加切片，注意...语法

	slice = append([]int{100, 200}, slice...) // 在切片前面添加元素,存在性能问题
	fmt.Println("len:", len(slice))           // 8
	fmt.Println("cap:", cap(slice))           // 10
	fmt.Println("slice is ", slice)

	// copy() 函数的使用格式如下：copy( destSlice, srcSlice []T) int
	var srcSlice = []int{1, 2, 3}
	var destSlice = make([]int, 2)
	n := copy(destSlice, srcSlice)
	fmt.Println("copied ", n, " elements")  // 2
	fmt.Println("destSlice is ", destSlice) // [1 2]

}

// make = 一次性分配好“底层数组 + 切片头”，剩下的扩容、拷贝、释放由 append & GC 帮你完成；
// 所以你可以把它当成“可扩容的动态数组”来用，而不用手动 malloc/free

// len 是切片当前包含的元素数量，可见区域
// cap 是切片底层数组的容量
